package com.hcj.springcloud.ChainOfResponsibilityPattern;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 责任链-demo2
 * 模拟spring的filter实现
 *
 * @author huangchangjin
 * @date 2023/11/28 11:25
 */
@Slf4j
public class Demo2 {
    static abstract class AbstractFilter {
        protected Integer order;
        protected AbstractFilter nextFilter;

        protected abstract void doFilter(String request);

        public void setNextFilter(AbstractFilter nextFilter) {
            this.nextFilter = nextFilter;
        }

        public void process(String request) {
            doFilter(request);

            if (nextFilter != null) {
                nextFilter.process(request);
            }
        }
    }

    static class FilterA extends AbstractFilter {
        public FilterA(Integer order) {
            this.order = order;
        }

        @Override
        protected void doFilter(String request) {
            log.info("FilterA request = {}", request);
        }
    }

    static class FilterB extends AbstractFilter {
        public FilterB(Integer order) {
            this.order = order;
        }

        @Override
        protected void doFilter(String request) {
            log.info("FilterB request = {}", request);
        }
    }

    static class FilterC extends AbstractFilter {
        public FilterC(Integer order) {
            this.order = order;
        }

        @Override
        protected void doFilter(String request) {
            log.info("FilterC request = {}", request);
        }
    }

    static class FilterD extends AbstractFilter {
        public FilterD(Integer order) {
            this.order = order;
        }

        @Override
        protected void doFilter(String request) {
            log.info("FilterD request = {}", request);
        }
    }

    static class MyFilterChain {
        static AbstractFilter genFilterChain() {
            // 1. 初始化过滤器
            AbstractFilter filterA = new FilterA(3);
            AbstractFilter filterB = new FilterB(2);
            AbstractFilter filterC = new FilterC(1);
            AbstractFilter filterD = new FilterD(-1);
            AbstractFilter filterDD = new FilterD(-1);
            // 2. 按 order 排序
            List<AbstractFilter> list = new ArrayList<>();
            list.add(filterB);
            list.add(filterDD);
            list.add(filterC);
            list.add(filterA);
            list.add(filterD);
            List<AbstractFilter> sortedFilter = list.stream().sorted(Comparator.comparingInt(x -> x.order)).collect(Collectors.toList());
            // 3. 串成链[D -> C -> B -> A]
            AbstractFilter rootFilter = null;
            for (int i = 0; i < sortedFilter.size() - 1; i++) {
                if (rootFilter == null) {
                    rootFilter = sortedFilter.get(0);
                }
                AbstractFilter filter = sortedFilter.get(i);
                AbstractFilter filterNext = sortedFilter.get(i + 1);
                if (filter != null && filterNext != null) {
                    filter.setNextFilter(filterNext);
                }
            }
            return rootFilter;
        }
    }

    @Test
    void test_main() {
        AbstractFilter filter = MyFilterChain.genFilterChain();
        if (filter != null) {
            filter.process("request_body");
        }
    }
}
